package cn.wps.solution.demo.service;

import cn.wps.solution.demo.entity.File;
import cn.wps.solution.demo.entity.User;
import cn.wps.solution.demo.repository.FileRepository;
import cn.wps.solution.demo.repository.UserRepository;
import cn.wps.solution.demo.util.RequestUtils;
import cn.wps.solution.weboffice.provider.v3.exception.FileNotExist;
import cn.wps.solution.weboffice.provider.v3.exception.InvalidToken;
import cn.wps.solution.weboffice.provider.v3.model.DownloadInfo;
import cn.wps.solution.weboffice.provider.v3.model.FileInfo;
import cn.wps.solution.weboffice.provider.v3.model.UserPermission;
import cn.wps.solution.weboffice.provider.v3.service.PreviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Comparator;
import java.util.Optional;

@Service
public class PreviewServiceImpl implements PreviewService {
    @Autowired
    private FileRepository fileRepository;

    @Autowired
    private UserRepository userRepository;

    @Value("${weboffice.provider.host:http://localhost:8080}")
    private String host;

    @Override
    public FileInfo fetchFileInfo(String fileId) {
        return fetchFile(fileId).toFileInfo();
    }


    // TODO liangzuobin optional is better
    File fetchFile(String fileId) {
        return Optional.ofNullable(fileId)
                .map(fileRepository::findByIdId)
                .map(Collection::stream)
                .flatMap(s -> s.max(Comparator.comparingInt(f -> f.getId().getVersion())))
                .orElseThrow(FileNotExist::new);
    }

    @Override
    public DownloadInfo fetchDownloadInfo(String fileId) {
        return Optional.ofNullable(fileId)
                .map(fileRepository::findByIdId)
                .map(Collection::stream)
                .flatMap(s -> s.max(Comparator.comparingInt(f -> f.getId().getVersion())))
                .map(f -> DownloadInfo.builder()
                        .url(String.format("%s/console/download/%s/%d", host, f.getId().getId(), f.getId().getVersion()))
                        .build())
                .orElseThrow(FileNotExist::new);
    }

    User fetchUserByToken() {
        // PAY ATTENTION token been considered as user.id here
        return Optional.of(RequestUtils.getCurrentRequest())
                .map(RequestUtils::getWebOfficeToken)
                .map(Long::parseLong)
                .flatMap(uid -> userRepository.findById(uid))
                .orElseThrow(InvalidToken::new);
    }

    @Override
    public UserPermission fetchUserPermission(String fileId) {
        fetchFile(fileId); // check file exists
        User user = fetchUserByToken();
        return UserPermission.builder()
                .userId(String.valueOf(user.getId()))
                .read(true)
                .update(true)
                .rename(true)
                .download(true)
                .copy(true)
                .comment(true)
                .history(true)
                .build();
    }
}
